<script setup lang="ts">
import { ref, onMounted, computed } from "vue";
import { VueFlow, useVueFlow, Position, MarkerType } from "@vue-flow/core";
import { processNodeList, equipmentList } from "@/assets/mock/mockData";
import type { ProcessNode } from "@/api/interface/index";
import type { Node, Edge } from "@vue-flow/core";
import { useRoute } from "vue-router";
import "@vue-flow/core/dist/style.css";
import FlowProcessNode from "@/components/ProcessNode/index.vue";
import { Operation, Connection, Document, Search, CirclePlus } from "@element-plus/icons-vue";
import { ElMessage } from "element-plus";
import useDragAndDrop from "@/hooks/useDragAndDrop";

// 初始化 VueFlow
const { onConnect } = useVueFlow();

// 状态管理
const nodes = ref<Node[]>([]);
const edges = ref<Edge[]>([]);

// 拖拽状态
const {
  isDragOver,
  onDragStart,
  onDragEnd,
  onDragOver: dragOverHandler,
  onDragLeave: dragLeaveHandler,
  onDrop
} = useDragAndDrop();

// 获取工序节点数据
const processNodes = ref<ProcessNode.ProcessNode[]>([]);
const productName = ref("");
// 跟踪哪些节点在画布上
const activeNodes = ref<Set<string>>(new Set());

const route = useRoute();
const productId = route.params.id as string;

// 控制详情对话框
const dialogVisible = ref(false);
const currentNodeData = ref<any>(null);

// 设备选择对话框
const equipmentDialogVisible = ref(false);
const currentNodeId = ref<string>("");
const currentProcessId = ref<string>("");
const searchEquipment = ref(""); // 添加设备搜索关键字

// 监听对话框关闭事件
const handleDialogClose = () => {
  searchEquipment.value = ""; // 清空搜索框
};

// 添加设备过滤计算属性
const filteredEquipmentList = computed(() =>
  equipmentList.value.filter(
    data => !searchEquipment.value || data.equipmentName?.toLowerCase().includes(searchEquipment.value.toLowerCase())
  )
);

// 计算节点顺序
const calculateNodeOrder = (nodes: Node[]) => {
  const nodeOrder = new Map<string, number>();
  let order = 1;

  // 根据边的连接关系构建节点顺序
  const visited = new Set<string>();
  const dfs = (nodeId: string) => {
    if (visited.has(nodeId)) return;
    visited.add(nodeId);
    nodeOrder.set(nodeId, order++);

    // 查找当前节点连接的下一个节点
    const nextEdge = edges.value.find(edge => edge.source === nodeId);
    if (nextEdge) {
      dfs(nextEdge.target);
    }
  };

  // 找到起始节点（没有入边的节点）
  const startNode = nodes.find(node => !edges.value.some(edge => edge.target === node.id));

  if (startNode) {
    dfs(startNode.id);
  }

  return nodeOrder;
};

// 初始化画布
const initializeCanvas = () => {
  console.log("开始初始化画布...");
  const productNodes = processNodeList.value.find(item => item.productId === productId);
  if (!productNodes) {
    console.log("未找到产品节点数据");
    return;
  }
  console.log("找到产品节点:", productNodes);

  // 设置产品名称
  productName.value = productNodes.productName;

  // 分离有序和无序节点
  const orderedNodes = productNodes.nodes.filter(node => node.order != null).sort((a, b) => (a.order || 0) - (b.order || 0));
  const unorderedNodes = productNodes.nodes.filter(node => node.order == null);

  console.log("有序节点:", orderedNodes);
  console.log("无序节点:", unorderedNodes);

  // 更新工具栏节点
  processNodes.value = [
    {
      ...productNodes,
      nodes: unorderedNodes
    }
  ];

  // 在画布上布置有序节点
  orderedNodes.forEach((node, index) => {
    const newNode = {
      id: node.nodeId,
      type: "custom",
      position: {
        x: 250,
        y: 100 + index * 150
      },
      data: {
        ...node,
        label: node.process.processName
      },
      sourcePosition: Position.Bottom,
      targetPosition: Position.Top
    };
    nodes.value.push(newNode);
    activeNodes.value.add(node.nodeId);
  });

  // 添加边连接有序节点
  for (let i = 0; i < orderedNodes.length - 1; i++) {
    edges.value.push({
      id: `edge_${orderedNodes[i].nodeId}-${orderedNodes[i + 1].nodeId}`,
      source: orderedNodes[i].nodeId,
      target: orderedNodes[i + 1].nodeId
    });
  }

  console.log("画布初始化完成 - 节点:", nodes.value);
  console.log("画布初始化完成 - 边:", edges.value);
};

onMounted(() => {
  initializeCanvas();
});

// 处理节点放置
const handleDrop = (event: DragEvent) => {
  const flowWrapper = document.querySelector(".vue-flow") as HTMLElement;
  if (!flowWrapper) return;

  const newNode = onDrop(event, flowWrapper);
  if (newNode && !activeNodes.value.has(newNode.id)) {
    nodes.value.push(newNode);
    activeNodes.value.add(newNode.id);
  }
  isDragOver.value = false;
};

// 添加默认配置
const defaultEdgeOptions = {
  animated: true,
  type: "smoothstep",
  markerEnd: {
    type: MarkerType.ArrowClosed,
    color: "#999999"
  },
  style: {
    stroke: "#999999",
    strokeWidth: 2
  }
};

// 显示节点详情
const showNodeDetails = (data: any) => {
  currentNodeData.value = data;
  dialogVisible.value = true;
};

// 返回上一页
const handleBack = () => {
  window.history.back();
};

// 保存当前流程图
const save = () => {
  console.log("开始保存流程图...");
  console.log("当前画布节点:", nodes.value);
  console.log("当前画布边:", edges.value);

  // 计算节点顺序
  const nodeOrder = calculateNodeOrder(nodes.value);
  console.log("计算的节点顺序:", nodeOrder);

  // 更新 processNodeList
  const productIndex = processNodeList.value.findIndex(item => item.productId === productId);
  if (productIndex === -1) {
    console.error("未找到对应的产品数据");
    return;
  }

  // 获取所有节点
  const allNodes = [...processNodeList.value[productIndex].nodes];

  // 更新节点顺序
  allNodes.forEach(node => {
    if (activeNodes.value.has(node.nodeId)) {
      // 节点在画布中，设置顺序
      node.order = nodeOrder.get(node.nodeId);
    } else {
      // 节点在工具栏中，清除顺序
      node.order = undefined;
    }
  });

  // 更新 processNodeList
  processNodeList.value[productIndex].nodes = allNodes;

  console.log("保存完成 - 更新后的数据:", processNodeList.value[productIndex]);
  ElMessage.success("保存成功");
};

// 处理节点连接
onConnect(params => {
  // 检查源节点是否已有输出连接
  const existingEdges = edges.value.filter(edge => edge.source === params.source);

  if (existingEdges.length === 0) {
    const newEdge = {
      id: `edge_${params.source}-${params.target}`,
      source: params.source,
      target: params.target,
      type: "smoothstep",
      markerEnd: {
        type: MarkerType.ArrowClosed,
        color: "#999999"
      },
      style: {
        stroke: "#999999",
        strokeWidth: 2
      }
    };
    edges.value.push(newEdge);
  }
});

// 处理节点点击返回工具栏
const handleNodeReturn = (nodeToReturn: Node) => {
  console.log("返回工具栏的节点:", nodeToReturn);
  // 从画布中移除节点
  nodes.value = nodes.value.filter(node => node.id !== nodeToReturn.id);
  // 移除相关的边
  edges.value = edges.value.filter(edge => edge.source !== nodeToReturn.id && edge.target !== nodeToReturn.id);
  // 从活动节点集合中移除
  activeNodes.value.delete(nodeToReturn.id);

  // 确保节点在工具栏中显示
  if (processNodes.value[0] && !processNodes.value[0].nodes.some(node => node.nodeId === nodeToReturn.data.nodeId)) {
    processNodes.value[0].nodes.push(nodeToReturn.data);
  }

  console.log("活动节点集合:", Array.from(activeNodes.value));
  console.log("工具栏节点:", processNodes.value[0].nodes);
};

// 处理节点点击
const onNodeClick = () => {
  // 节点点击事件现在由子组件中的按钮处理
};

// 处理绑定设备
const handleBindEquipment = (nodeId: string, processId: string) => {
  currentNodeId.value = nodeId;
  currentProcessId.value = processId;
  equipmentDialogVisible.value = true;
};

// 选择设备
const handleSelectEquipment = (equipment: any) => {
  // 找到当前产品的节点列表
  const productIndex = processNodeList.value.findIndex(item => item.productId === productId);
  if (productIndex === -1) return;

  // 找到当前节点
  const nodeIndex = processNodeList.value[productIndex].nodes.findIndex(node => node.nodeId === currentNodeId.value);
  if (nodeIndex === -1) return;

  // 更新节点的设备信息
  processNodeList.value[productIndex].nodes[nodeIndex].equipment = equipment;

  // 更新当前画布上的节点数据
  const node = nodes.value.find(n => n.id === currentNodeId.value);
  if (node) {
    node.data.equipment = equipment;
  }

  equipmentDialogVisible.value = false;
  ElMessage.success("设备绑定成功");
};
</script>

<template>
  <div class="process-flow">
    <!-- 头部 -->
    <div class="header">
      <button class="back-button" @click="handleBack">返回</button>
      <span class="title">产品生产装配碳排放值收集 / {{ productName }}</span>
      <div class="header-buttons">
        <el-button type="primary" link :icon="Document" @click="save">保存</el-button>
      </div>
    </div>

    <div class="main-content">
      <!-- 工具栏 -->
      <aside class="sidebar">
        <div class="sidebar-header">
          <div class="sidebar-title-wrapper">
            <el-icon><Operation /></el-icon>
            <span class="sidebar-title">工序节点</span>
          </div>
        </div>
        <div class="sidebar-desc">拖拽节点到右侧画布进行工序流程配置</div>
        <div class="sidebar-nodes">
          <div
            v-for="processNode in processNodes[0]?.nodes"
            :key="processNode.nodeId"
            v-show="!activeNodes.has(processNode.nodeId)"
            class="sidebar-node"
            draggable="true"
            @dragstart="onDragStart($event, processNode)"
            @dragend="onDragEnd"
          >
            <div class="node-content">
              <el-icon><Connection /></el-icon>
              <span class="node-label">{{ processNode.process.processName }}</span>
            </div>
            <div class="node-info">
              <span class="node-id">{{ processNode.process.processId }}</span>
            </div>
          </div>
        </div>
      </aside>

      <!-- 流程图画布 -->
      <div class="canvas">
        <VueFlow
          v-model="nodes"
          :edges="edges"
          :default-edge-options="defaultEdgeOptions"
          @dragover="dragOverHandler"
          @dragleave="dragLeaveHandler"
          @drop="handleDrop"
          @node-click="onNodeClick"
          fit-view-on-init
        >
          <template #node-custom="nodeProps">
            <FlowProcessNode
              :id="nodeProps.id"
              :data="nodeProps.data"
              @return-to-toolbar="handleNodeReturn"
              @show-details="showNodeDetails"
              @bind-equipment="handleBindEquipment"
            />
          </template>
        </VueFlow>
      </div>
    </div>

    <!-- 详情对话框 -->
    <el-dialog
      v-model="dialogVisible"
      title="工序节点详情"
      width="65%"
      :close-on-click-modal="false"
      destroy-on-close
      append-to-body
    >
      <div v-if="currentNodeData" class="node-details">
        <!-- 工序信息 -->
        <div class="detail-section">
          <h3 class="section-title">工序信息</h3>
          <div v-if="!currentNodeData?.process">暂无工序数据</div>
          <el-descriptions v-else :column="1" border>
            <el-descriptions-item label="工序名称">
              {{ currentNodeData.process.processName }}
            </el-descriptions-item>
            <el-descriptions-item label="工序编号">
              {{ currentNodeData.process.processId }}
            </el-descriptions-item>
            <el-descriptions-item label="工序描述" :span="2">
              {{ currentNodeData.process.description }}
            </el-descriptions-item>
          </el-descriptions>
        </div>

        <!-- 设备信息 -->
        <div class="detail-section">
          <h3 class="section-title">设备信息</h3>
          <div v-if="!currentNodeData?.equipment">暂无设备数据</div>
          <el-descriptions v-else :column="1" border>
            <el-descriptions-item label="设备名称">
              {{ currentNodeData.equipment.equipmentName }}
            </el-descriptions-item>
            <el-descriptions-item label="设备编号">
              {{ currentNodeData.equipment.equipmentId }}
            </el-descriptions-item>
            <el-descriptions-item label="设备功率"> {{ currentNodeData.equipment.ratedPower }}kW </el-descriptions-item>
            <el-descriptions-item label="设备描述" :span="2">
              {{ currentNodeData.equipment.functionDescription }}
            </el-descriptions-item>
            <el-descriptions-item label="安全说明" :span="2">
              {{ currentNodeData.equipment.safetyInstructions }}
            </el-descriptions-item>
          </el-descriptions>
        </div>

        <!-- 物料信息 -->
        <div class="detail-section">
          <h3 class="section-title">物料信息</h3>
          <div v-if="!currentNodeData?.materials?.length">暂无物料数据</div>
          <el-table
            v-else
            :data="currentNodeData.materials"
            border
            style="width: 100%"
            :header-cell-style="{
              background: '#f5f7fa',
              color: '#606266',
              height: '50px',
              fontWeight: 600
            }"
            :cell-style="{
              height: '45px'
            }"
          >
            <el-table-column prop="materialId" label="物料编号" min-width="120" />
            <el-table-column prop="materialName" label="物料名称" min-width="150" />
            <el-table-column prop="materialType" label="物料类型" min-width="120">
              <template #default="scope">
                {{ scope.row.materialType === 2 ? "部件" : "原材料" }}
              </template>
            </el-table-column>
            <el-table-column prop="sourceType" label="来源类型" min-width="120">
              <template #default="scope">
                {{ scope.row.sourceType === 1 ? "自制" : "外购" }}
              </template>
            </el-table-column>
            <el-table-column prop="createTime" label="创建时间" width="180" fixed="right" class-name="create-time-column" />
          </el-table>
        </div>
      </div>
    </el-dialog>

    <!-- 设备选择对话框 -->
    <el-dialog
      v-model="equipmentDialogVisible"
      title="选择设备"
      width="1200px"
      destroy-on-close
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      class="custom-dialog"
      @close="handleDialogClose"
    >
      <el-input
        v-model="searchEquipment"
        size="small"
        placeholder="请输入设备名称"
        clearable
        :prefix-icon="Search"
        style="margin-bottom: 30px"
      />
      <el-table
        :data="filteredEquipmentList"
        style="width: 100%"
        max-height="400px"
        border
        :header-cell-style="{
          background: '#f5f7fa',
          color: '#606266',
          height: '45px',
          fontWeight: 600
        }"
        :cell-style="{
          height: '45px'
        }"
      >
        <el-table-column prop="equipmentId" label="设备编号" min-width="120" />
        <el-table-column prop="equipmentName" label="设备名称" min-width="120" />
        <el-table-column prop="ratedPower" label="额定功率" min-width="100">
          <template #default="scope"> {{ scope.row.ratedPower }}kW </template>
        </el-table-column>
        <el-table-column prop="functionDescription" label="功能描述" min-width="240" show-overflow-tooltip />
        <el-table-column prop="safetyInstructions" label="操作文本" min-width="240" show-overflow-tooltip />
        <el-table-column prop="createTime" label="创建时间" min-width="180" />
        <el-table-column align="center" width="150" fixed="right" label="操作">
          <template #default="scope">
            <el-button type="primary" link :icon="CirclePlus" @click="handleSelectEquipment(scope.row)"> 选择 </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-dialog>
  </div>
</template>

<style scoped>
.header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 20px;
  background-color: #ffffff;
  border-bottom: 1px solid #dddddd;
  border-radius: 8px;
}
.header-buttons {
  display: flex;
  gap: 10px;
  margin-left: auto;
}
.back-button {
  padding: 8px 12px;
  margin-right: 20px;
  font-size: 14px;
  color: white;
  cursor: pointer;
  background-color: #009688;
  border: none;
  border-radius: 4px;
  transition: background-color 0.2s ease;
}
.back-button:hover {
  background-color: #007d6a;
}
.title {
  font-size: 18px;
  font-weight: bold;
  color: #333333;
}
.el-button {
  padding: 8px 12px;
  font-size: 14px;
}
.process-flow {
  display: grid;
  grid-template-rows: auto 1fr;
  width: 100%;
  height: 100vh;
}
.main-content {
  display: flex;
  height: 100%;
  overflow: hidden;
}
.sidebar {
  width: 200px;
  padding: 16px;
  background-color: var(--el-bg-color-page);
  border-right: 1px solid var(--el-border-color-light);
  box-shadow: 4px 0 8px -4px rgb(0 0 0 / 5%);
}
.sidebar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 12px;
  margin-bottom: 12px;
  border-bottom: 1px dashed var(--el-border-color);
}
.sidebar-title-wrapper {
  display: flex;
  gap: 8px;
  align-items: center;
}
.sidebar-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--el-text-color-regular);
}
.sidebar-desc {
  padding: 8px 12px;
  margin-bottom: 16px;
  font-size: 12px;
  color: var(--el-text-color-secondary);
  background-color: var(--el-color-info-light-9);
  border-radius: 4px;
}
.sidebar-nodes {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: calc(100vh - 200px);
  overflow-y: auto;
}
.sidebar-node {
  padding: 12px;
  cursor: move;
  user-select: none;
  background-color: var(--el-bg-color);
  border: 1px solid var(--el-border-color);
  border-radius: 4px;
  transition: all 0.3s ease;
}
.node-content {
  display: flex;
  gap: 8px;
  align-items: center;
}
.node-label {
  font-size: 14px;
  color: var(--el-text-color-primary);
}
.node-info {
  padding-top: 8px;
  margin-top: 8px;
  border-top: 1px dashed var(--el-border-color-lighter);
}
.node-id {
  font-size: 12px;
  color: var(--el-text-color-secondary);
}
.sidebar-node:hover {
  color: var(--el-color-primary);
  background-color: var(--el-color-primary-light-9);
  border-color: var(--el-color-primary-light-5);
  transform: translateX(2px);
}
.sidebar-nodes::-webkit-scrollbar {
  width: 4px;
}
.sidebar-nodes::-webkit-scrollbar-thumb {
  background-color: var(--el-border-color-lighter);
  border-radius: 2px;
}
.sidebar-nodes::-webkit-scrollbar-track {
  background-color: transparent;
}
.canvas {
  position: relative;
  flex-grow: 1;
  height: 100%;
}
.vue-flow {
  background-color: #f8f9fa;
}
.node-details {
  padding: 0 20px;
}
.detail-section {
  margin-bottom: 24px;
}
.section-title {
  padding-left: 10px;
  margin: 0 0 16px;
  font-size: 16px;
  font-weight: 600;
  color: var(--el-color-primary);
  border-left: 4px solid var(--el-color-primary);
}
:deep(.el-descriptions) {
  padding: 12px;
  background-color: var(--el-bg-color-page);
  border-radius: 4px;
}
:deep(.el-descriptions__label) {
  font-weight: 600;
  color: var(--el-text-color-primary);
}
:deep(.el-table) {
  --el-table-border-color: var(--el-border-color-lighter);
  --el-table-header-bg-color: #f5f7fa;
}
:deep(.create-time-column) {
  position: sticky !important;
  right: 0;
  background-color: var(--el-table-bg-color);
  border-left: 1px solid var(--el-table-border-color);
}
:deep(.create-time-column .cell) {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.node-details .detail-section > div:not(.section-title, .el-descriptions, .el-table) {
  padding: 16px;
  color: var(--el-text-color-secondary);
  text-align: center;
  background-color: var(--el-bg-color-page);
  border-radius: 4px;
}
</style>
